﻿using System.Windows;
using System.Windows.Controls;

namespace ICodeShare.UI.Controls
{
    /// <summary>
    /// Represents a control that indicates that an operation is ongoing.
    /// </summary>
    [TemplateVisualState(GroupName = GroupActiveStates, Name = StateInactive)]
    [TemplateVisualState(GroupName = GroupActiveStates, Name = StateActive)]
    [TemplatePart(Name = PART_Border, Type = typeof(Border))]
    public class LoadingIndicator : Control
    {
        private const string GroupActiveStates = "ActiveStates";
        private const string StateInactive = "Inactive";
        private const string StateActive = "Active";
        private const string PART_Border = "PART_Border";

        // Variables
        protected Border border;

        static LoadingIndicator()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(LoadingIndicator), new FrameworkPropertyMetadata(typeof(LoadingIndicator)));
        }

        #region IsActive 是否活跃

        /// <summary>
        /// Gets or sets a value that indicates whether the <see cref="ModernProgressRing"/> is showing progress.
        /// </summary>
        public bool IsActive
        {
            get { return (bool)GetValue(IsActiveProperty); }
            set { SetValue(IsActiveProperty, value); }
        }

        /// <summary>
        /// Identifies the IsActive property.
        /// </summary>
        public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(
            "IsActive",
            typeof(bool),
            typeof(LoadingIndicator),
            new PropertyMetadata(false, OnIsActiveChanged));

        #endregion IsActive 是否活跃

        #region SpeedRatio 动画速度

        /// <summary>
        /// Identifies the <see cref="LoadingIndicators.WPF.LoadingIndicator.SpeedRatio"/> dependency property.
        /// </summary>
        public static readonly DependencyProperty SpeedRatioProperty = DependencyProperty.Register(
            "SpeedRatio",
            typeof(double),
            typeof(LoadingIndicator),
            new PropertyMetadata(1d, OnSpeedRatioChanged));

        /// <summary>
        /// Get/set the speed ratio of the animation.
        /// </summary>
        public double SpeedRatio
        {
            get { return (double)GetValue(SpeedRatioProperty); }
            set { SetValue(SpeedRatioProperty, value); }
        }

        #endregion SpeedRatio 动画速度

        private void GotoCurrentState(bool animate)
        {
            var state = this.IsActive ? StateActive : StateInactive;

            VisualStateManager.GoToState(this, state, animate);
        }

        /// <summary>
        /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            border = (Border)GetTemplateChild(PART_Border);
            GotoCurrentState(false);
            if (border != null)
            {
                VisualStateManager.GoToElementState(border, (this.IsActive ? "Active" : "Inactive"), false);
                foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(border))
                {
                    if (group.Name == "ActiveStates")
                    {
                        foreach (VisualState state in group.States)
                        {
                            if (state.Name == "Active")
                            {
                                state.Storyboard.SetSpeedRatio(border, this.SpeedRatio);
                            }
                        }
                    }
                }
            }
        }

        private static void OnIsActiveChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((LoadingIndicator)o).GotoCurrentState(true);
        }

        private static void OnSpeedRatioChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            LoadingIndicator li = (LoadingIndicator)o;

            if (li.border == null || li.IsActive == false)
            {
                return;
            }

            foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(li.border))
            {
                if (group.Name == "ActiveStates")
                {
                    foreach (VisualState state in group.States)
                    {
                        if (state.Name == "Active")
                        {
                            state.Storyboard.SetSpeedRatio(li.border, (double)e.NewValue);
                        }
                    }
                }
            }
        }
    }
}